JSON = new function () {
	this.decode = function () {
		var filter, result, self, tmp;
		if ($$("toString")) {
			switch (arguments.length) {
			  case 2:
				self = arguments[0];
				filter = arguments[1];
				break;
			  case 1:
				if ($[typeof arguments[0]](arguments[0]) === Function) {
					self = this;
					filter = arguments[0];
				} else {
					self = arguments[0];
				}
				break;
			  default:
				self = this;
				break;
			}
			if (rc.test(self)) {
				try {
					result = e("(".concat(self, ")"));
					if (filter && result !== null && (tmp = $[typeof result](result)) && (tmp === Array || tmp === Object)) {
						for (self in result) {
							result[self] = v(self, result) ? filter(self, result[self]) : result[self];
						}
					}
				}
				catch (z) {
				}
			} else {
				throw new JSONError("bad data");
			}
		}
		return result;
	};
	this.encode = function () {
		var self = arguments.length ? arguments[0] : this, result, tmp;
		if (self === null) {
			result = "null";
		} else {
			if (self !== undefined && (tmp = $[typeof self](self))) {
				switch (tmp) {
				  case Array:
					result = [];
					for (var i = 0, j = 0, k = self.length; j < k; j++) {
						if (self[j] !== undefined && (tmp = JSON.encode(self[j]))) {
							result[i++] = tmp;
						}
					}
					result = "[".concat(result.join(","), "]");
					break;
				  case Boolean:
					result = String(self);
					break;
				  case Date:
					result = "\"".concat(self.getFullYear(), "-", d(self.getMonth() + 1), "-", d(self.getDate()), "T", d(self.getHours()), ":", d(self.getMinutes()), ":", d(self.getSeconds()), "\"");
					break;
				  case Function:
					break;
				  case Number:
					result = isFinite(self) ? String(self) : "null";
					break;
				  case String:
					result = "\"".concat(self.replace(rs, s).replace(ru, u), "\"");
					break;
				  default:
					var i = 0, key;
					result = [];
					for (key in self) {
						if (self[key] !== undefined && (tmp = JSON.encode(self[key]))) {
							result[i++] = "\"".concat(key.replace(rs, s).replace(ru, u), "\":", tmp);
						}
					}
					result = "{".concat(result.join(","), "}");
					break;
				}
			}
		}
		return result;
	};
	this.toDate = function () {
		var self = arguments.length ? arguments[0] : this, result;
		if (rd.test(self)) {
			result = new Date;
			result.setHours(i(self, 11, 2));
			result.setMinutes(i(self, 14, 2));
			result.setSeconds(i(self, 17, 2));
			result.setMonth(i(self, 5, 2) - 1);
			result.setDate(i(self, 8, 2));
			result.setFullYear(i(self, 0, 4));
		} else {
			if (rt.test(self)) {
				result = new Date(self * 1000);
			}
		}
		return result;
	};
	var c = {"\b":"b", "\t":"t", "\n":"n", "\f":"f", "\r":"r", "\"":"\"", "\\":"\\", "/":"/"}, 
	d = function (n) {
		return n < 10 ? "0".concat(n) : n;
	}, 
	e = function (c, f, e) {
		e = eval;
		delete eval;
		if (typeof eval === "undefined") {
			eval = e;
		}
		f = eval("" + c);
		eval = e;
		return f;
	}, 
	i = function (e, p, l) {
		return 1 * e.substr(p, l);
	}, 
	p = ["", "000", "00", "0", ""], rc = null, rd = /^[0-9]{4}\-[0-9]{2}\-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}$/, rs = /(\x5c|\x2F|\x22|[\x0c-\x0d]|[\x08-\x0a])/g, rt = /^([0-9]+|[0-9]+[,\.][0-9]{1,3})$/, ru = /([\x00-\x07]|\x0b|[\x0e-\x1f])/g, s = function (i, d) {
		return "\\".concat(c[d]);
	}, 
	u = function (i, d) {
		var n = d.charCodeAt(0).toString(16);
		return "\\u".concat(p[n.length], n);
	}, 
	v = function (k, v) {
		return $[typeof result](result) !== Function && (v.hasOwnProperty ? v.hasOwnProperty(k) : v.constructor.prototype[k] !== v[k]);
	}, 
	$ = {"boolean":function () {
		return Boolean;
	}, 
	"function":function () {
		return Function;
	}, 
	"number":function () {
		return Number;
	}, 
	"object":function (o) {
		return o instanceof o.constructor ? o.constructor : null;
	}, 
	"string":function () {
		return String;
	}, 
	"undefined":function () {
		return null;
	}}, 
	$$ = function (m) {
		function $(c, t) {
			t = c[m];
			delete c[m];
			try {
				e(c);
			}
			catch (z) {
				c[m] = t;
				return 1;
			}
		}
		return $(Array) && $(Object);
	};
	try {
		rc = new RegExp("^(\"(\\\\.|[^\"\\\\\\n\\r])*?\"|[,:{}\\[\\]0-9.\\-+Eaeflnr-u \\n\\r\\t])+?$");
	}
	catch (z) {
		rc = /^(true|false|null|\[.*\]|\{.*\}|".*"|\d+|\d+\.\d+)$/;
	}
};
